package com.acme.mock;

import com.acme.domain.bank.Bank;
import com.acme.service.bank.BankDataLoader;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class BankServer {
    Bank bank;
	ServerSocket providerSocket;
	Socket connection = null;
	ObjectOutputStream out;
	ObjectInputStream in;
	String message;
    BankDataLoader bankDataLoader;
    public static final String WAITING = "Waiting for connection";
    public static final String RCVD = "Connection received from ";
    public static final String SUCESS = "Connection successful";
    public static final String BYE = "bye";
    public static final String ADDED = "Account added!";
    public static final String WRONG_FEED = "Wrong feed string";
    public static final String UNKN_FORMAT = "Data received in unknown format";
    public static final String SERVER = "server>";
    public static final String ADD = "add>";
    public static final String CLIENT = "client>";

	public BankServer(Bank bank, BankDataLoader bankDataLoader) {
        this.bank = bank;
        this.bankDataLoader = bankDataLoader;
	}

	public void run() {
		try {
			// 1. creating a server socket
			providerSocket = new ServerSocket(2007, 10);
			// 2. Wait for connection
			System.out.println(WAITING);
			connection = providerSocket.accept();
			System.out.println(RCVD
					+ connection.getInetAddress() + connection.getInetAddress().getHostName());
			// 3. get Input and Output streams
			out = new ObjectOutputStream(connection.getOutputStream());
			out.flush();
			in = new ObjectInputStream(connection.getInputStream());
			sendMessage(SUCESS);
			// 4. The two parts communicate via the input and output streams
			do {
				try {
					message = (String) in.readObject();
					System.out.println(CLIENT + message);
					if (message.equals(BYE))
						sendMessage(BYE);
                    else if (message.startsWith(ADD)) {
                        try{
                            bankDataLoader.getMapandLoad(message.substring(4, message.length()), bank);
                            sendMessage(ADDED);
                        }
                        catch (Exception e){
                            System.err.println(WRONG_FEED);
                        }
                    }
				} catch (ClassNotFoundException classnot) {
					System.err.println(UNKN_FORMAT);
				}
			} while (!message.equals(BYE));
		} catch (IOException ioException) {
			ioException.printStackTrace();
		} finally {
			// 4: Closing connection
			try {
				in.close();
				out.close();
				providerSocket.close();
			} catch (IOException ioException) {
				ioException.printStackTrace();
			}
		}
	}

	void sendMessage(final String msg) {
		try {
			out.writeObject(msg);
			out.flush();
			System.out.println(SERVER + msg);
		} catch (IOException ioException) {
			ioException.printStackTrace();
		}
	}
}
